﻿using ChessTest.Chess.Items;
using org.xisoft.game.utils.game;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChessTest.Chess.Algorithms
{
    /// <summary>
    /// 极大极小
    /// </summary>
    public class MaxMinSearchAlgorithm : AiAlgorithm
    {

        public override MoveAction Search(AiChessboard aiChessboard, int depth)
        {


            return Max(aiChessboard as AiChessboard,depth);

        }

        private MoveAction Max(AiChessboard aiChessboard,int depth)
        {
            if (depth <= 0)
            {
                return new MoveAction {Score=Int32.MinValue };
            }


            MoveAction bestChildstep = null;
            aiChessboard.ForeachMoviesChess(chessman =>
            {

                List<Point> points = chessman.GetCanMoveList(aiChessboard);
                foreach (Point point in points)
                {
                    Chessman man = aiChessboard.GetChessman(point.X, point.Y);

                    aiChessboard.Move(chessman, point.X, point.Y);
                    MoveAction step = Min(aiChessboard,depth - 1);
                    aiChessboard.Undo();

                    long score =0;
                    if (man != null)
                        score += man.Score;
                    if(step == null)
                    {
                        score += 200;//对方无棋可走
                    }else
                    {
                        score += step.Score;
                    }

                    if (bestChildstep == null || bestChildstep.Score < score)
                    {
                        if (bestChildstep == null)
                            bestChildstep = new MoveAction();
                        bestChildstep.Score = score;
                        bestChildstep.CurrentChessman = chessman;
                        bestChildstep.ToX = point.X;
                        bestChildstep.ToY = point.Y;
                        bestChildstep.FromX = chessman.PositionX;
                        bestChildstep.FromY = chessman.PositionY;
                        bestChildstep.OldChessman = man;

                    }
                    
                }
            });
            return bestChildstep;
        }

        private MoveAction Min(AiChessboard aiChessboard,int depth)
        {
            MoveAction bestChildstep = null;
            if (depth <= 0)
            {
                return new MoveAction { Score = Int32.MaxValue };
            }

            for (int x = 0; x < aiChessboard.MaxX; x++)
                for (int y = 0; y < aiChessboard.MaxY; y++)
                {
                    Chessman chessman = aiChessboard.GetChessman(x, y);
                    if (chessman == null || chessman.IsBlack != aiChessboard.IsCurrentBlackMove) continue;

                    List<Point> points = chessman.GetCanMoveList(aiChessboard);
                    foreach (Point point in points)
                    {
                        Chessman man = aiChessboard.GetChessman(point.X, point.Y);

                        aiChessboard.Move(chessman, point.X, point.Y);
                        MoveAction step = Max(aiChessboard,depth - 1);
                        aiChessboard.Undo();

                        long score = 0;
                        if (man != null)
                            score -= man.Score;
                        if (step == null)
                        {
                            score -= 200;//对方无棋可走
                        }
                        else
                        {
                            score += step.Score;
                        }

                        if (bestChildstep == null || bestChildstep.Score > score)
                        {
                            if (bestChildstep == null)
                                bestChildstep = new MoveAction();
                            bestChildstep.Score = score;
                            bestChildstep.CurrentChessman = chessman;
                            bestChildstep.ToX = point.X;
                            bestChildstep.ToY = point.Y;
                            bestChildstep.FromX = chessman.PositionX;
                            bestChildstep.FromY = chessman.PositionY;
                            bestChildstep.OldChessman = man;

                        }

                    }
                }
            return bestChildstep;
        }

    }
}
